/** 引入中国全省市区的数据 **/
import {
  codeToText
} from "element-china-area-data";
import { EventBus } from '@/views/youshuda/utils/event-bus';

/**
 * 判断对象是否“不为空”
 * @param obj
 * @returns {boolean}
 */
export function isNotEmpty(obj) {
  if (obj == null || obj == undefined){
    return false
  }
  // 先判断是否为数组：数组的 constructor 是 Array，且 length 为 0 时是空数组
  if (Array.isArray(obj)) {
    return obj.length !== 0;
  }
  // 再判断是否为对象（排除 null，因为 typeof null 会返回 'object'）
  if (typeof obj === 'object') {
    // 通过 Object.keys 获取对象自有可枚举属性，长度为 0 则是空对象
    return Object.keys(obj).length !== 0;
  }
  if(typeof obj =='boolean'){
    return true
  }
  if(typeof obj =='number'){
    return typeof !Number.isNaN(obj) && Number.isFinite(obj);
  }
  if (obj != undefined && obj != 'undefined' && obj != null && obj != '') {
    return true
  }
  return false
}

/**
 * 判断对象是否“为空”
 * @param obj
 * @returns {boolean}
 */
export function isEmpty(obj) {
  return !isNotEmpty(obj);
}

/**
 * 特殊字符处理
 * @param content
 * @returns {*}
 */
export function escapeDeal(content){
  if(isNotEmpty(content)){
    content = content.replace(/&lt;/gi, '<'); //小于符号处理
    content = content.replace(/&gt;/gi, '>'); //大于符号处理
    content = content.replace(/&apos;/gi, '\''); //单引号处理
    content = content.replace(/&quot;/gi, '\"'); //双引号处理
    content = content.replace(/&amp;/gi, '&'); //&号处理
  }
  return content
}

/**
 * 将字符串转boolean
 * @param obj
 * @returns {boolean}
 */
export function dealBoolean(obj){
  if(obj==true || obj=='true' || obj=='TRUE'){
    return true;
  }
  return false;
}

/**
 * 下拉列表翻译
 **/
export function translatorFormatter(row, item){
  let showTxt = ''
  switch (item.htmlType) {
    case 'date'://日期控件
      showTxt = this.parseTime(row[item.columnName], '{y}-{m}-{d}')
      break
    case 'datetime'://日期时间控件
      showTxt = this.parseTime(row[item.columnName], '{y}-{m}-{d} {hh}:{mi}:{ss}')
      break
    case 'password'://密码控件
      showTxt = '******'
      break
    case 'radio'://单选框
      showTxt = this.selectDictLabel(item.dictItems, row[item.columnName])
      break
    case 'input'://文本框
    case 'textarea'://文本域
    case 'number'://数字类型
    case 'editor'://富文本控件
      let _showTxt = ''
      if(this.isNotEmpty(item['dataDesensitizeLogic'])){
        //当前存在信息需要脱敏处理
        _showTxt = evalDataDesensitizeLogic(row[item.columnName],item['dataDesensitizeLogic'])
      }
      showTxt = _showTxt || row[item.columnName]
      break
    case 'select'://下拉框
    case 'allowCreateSelect'://下拉框
    case 'multipleSelect'://多选下拉框
    case 'multipleallowCreateSelect'://多选下拉框
    case 'checkbox'://复选框
      showTxt = this.selectDictLabels(item.dictItems, row[item.columnName], ',')
      break
    case 'CascaderArea': // 级联选择
      try{
        let content = "";
        let data=row[item.columnName];
        if (typeof data == 'string') {
          data = data.split(',')
        }
        data.map((item) => (content += codeToText[item] + "/")); //将级联值拼接一起
        if(this.isNotEmpty(content)){
          content = content.substring(0,content.lastIndexOf("/"))
        }
        showTxt = content
      }catch (e) {
        showTxt = row[item.columnName]
      }
      break
    default:
      showTxt = row[item.columnName]
      break
  }
  return showTxt
}

/** 数据脱敏处理 **/
export function evalDataDesensitizeLogic(info,desensitizeLogic) {
  if (desensitizeLogic) {
    /** 特殊字符处理 **/
    desensitizeLogic = escapeDeal(desensitizeLogic);
    // 创建函数对象
    const func = new Function("info",desensitizeLogic);
    return func.call(this,info);
  }
  return info;
}

/** 生成唯一标识 **/
export function generateNumTag() {
  return parseInt(Math.random() * (999999999 - 100000000) + 10)
}

/** 随机生成uuid **/
export function generateUuid() {
  var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  var uuid = [],
    i;
  var len = 32
  if (len) {
    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * chars.length];
  } else {
    var r;
    for (i = 0; i < 32; i++) {
      if (!uuid[i]) {
        r = 0 | Math.random() * 16;
        uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
      }
    }
  }
  return uuid.join('');
}

/**
 * 驼峰命名转换
 * @param str
 * @returns {*}
 */
export function toCamelCase(str) {
  if(str==undefined || str==null || str==''){
    return str
  }
  let reg=/_+(\w)/g;
  let result=str.replace(reg,function(){
    if(arguments[2])return (arguments[1]).toUpperCase();
    else return arguments[0];
  });
  return result;
}

/**
 * 成功消息提示
 * @param msg
 */
export function msgSuccess(msg) {
  this.$message({ showClose: true, message: msg, type: 'success' })
}

/**
 * 失败消息提示
 * @param msg
 */
export function msgError(msg) {
  this.$message({ showClose: true, message: msg, type: 'error' })
}


/**
 * 根据指定的开始字符与结束字符，截取字符串中的内容
 */
export function substringBetween(str,start,end) {
  if(!isNotEmpty(str) || !isNotEmpty(start) || !isNotEmpty(start)){
    return str
  }
  let sIndex=str.indexOf(start);
  if(sIndex>-1){
    let eIndex=str.indexOf(end,sIndex+start.length)
    if(eIndex>-1){
      return str.substring(sIndex+start.length,eIndex)
    }
  }
  return str
}

/**
 * 判断对象是否存在于数组中
 * @param arr
 * @param obj
 * @returns {*}
 */
export function objectExistsInArray(arr, obj) {
  return arr.some(element => JSON.stringify(element) === JSON.stringify(obj));
}


/**
 * 获取集合、对象中指定的属性值
 * @param data
 * @param property
 * @returns {*[]}
 */
export function getPropertyValues(data, property) {
  const values = [];
  function traverse(obj) {
    if (obj[property]) {
      values.push(obj[property]);
    }
    if (obj.children && Array.isArray(obj.children)) {
      obj.children.forEach(child => {
        traverse(child);
      });
    }
  }
  if (Array.isArray(data)) {
    data.forEach(item => {
      traverse(item);
    });
  } else {
    traverse(data);
  }
  return values;
}

/**
 * 判断集合或集合中子对象是否包含指定值
 * @param collection
 * @param propertyName
 * @returns {boolean}
 */
export function hasPropertyInCollection(collection, propertyName, propertyValue) {
  function checkObject(obj) {
    if (obj[propertyName]==propertyValue) {
      return true;
    }
    if (obj.children && Array.isArray(obj.children)) {
      for (let child of obj.children) {
        if (checkObject(child)) {
          return true;
        }
      }
    }
    return false;
  }

  for (let item of collection) {
    if (checkObject(item)) {
      return true;
    }
  }
  return false;
}

/**
 * 将字母下划线转驼峰
 * @param str
 * @returns {*}
 */
export function underscoreToCamelCase(str) {
  return str.replace(/_([a-z])/g, (match, p1) => p1.toUpperCase());
}

/**
 * 驼峰命名转下划线小写格式
 * @param camelStr
 * @returns {*}
 */
export function camelToSnake(camelStr) {
  if(camelStr == null || camelStr == undefined){
    return ""
  }
  // 在大写字母前插入下划线，然后转为小写
  return camelStr.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)
    // 处理首字母大写的情况（如 PascalCase）
    .replace(/^_/, '');
}
/**
 * 字符串转时间
 * @param str
 * @param format
 * @returns {Date}
 */
export function parseDate(str, format) {
  const [datePart, timePart] = str.split(' ');
  const [year, month, day] = datePart.split(format).map(Number);
  const [hour = 0, minute = 0, second = 0] = (timePart || '').split(':').map(Number);
  // 注意：月份从0开始，所以要减1
  return new Date(year, month - 1, day, hour, minute, second);
}

/**
 * 格式化时间
 * @param date
 * @param format
 * @returns {*}
 */
export function formatDate(date, format) {
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const day = String(date.getDate()).padStart(2, '0');
  const hour = String(date.getHours()).padStart(2, '0');
  const minute = String(date.getMinutes()).padStart(2, '0');
  const second = String(date.getSeconds()).padStart(2, '0');

  return format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hour)
    .replace('mm', minute)
    .replace('ss', second);
}

/**
 * 将b对象中的属性合并到a对象中，存在相同属性时以a为准
 * @param a
 * @param b
 * @param skipProperty 需要跳过不处理的属性，如：['children']
 * @returns {*}
 */
export function mergeObjects(a, b, skipProperty) {
  for (const key in b) {
    if(skipProperty.indexOf(key)>-1){
      continue;
    }
    // 仅在a中不存在该属性时才复制
    if (!a.hasOwnProperty(key)) {
      a[key] = b[key];
    }
  }
}

/**
 * 打开指定菜单
 * @param menuId 菜单ID
 * @param isReload 是否强制刷新页面
 */
export function openAssignMenu(menuId,isReload=false) {
  if(menuId){
    let menuPath =this.$store.getters.menuPathInfo[menuId]
    if(this.isEmpty(menuPath)){
      menuPath =  '/'
      isReload = true
    }
    this.$router.push({path: menuPath}).then(res=>{
      if (isReload){
        location.reload(true);
      }
    }).catch(() => {});
  }
}

/**
 * 模拟点击指定按钮
 * @param btnEventName 按钮注册的事件名
 */
export function clickAssignButton(btnEventTag) {
  if(btnEventTag){
    let btnEventFun =this.$store.getters.btnsEventInfo[btnEventTag]
    // 触发全局事件
    EventBus.$emit(btnEventFun);
  }
}


/**
 * 生成BuildSpeak唯一标识
 * @param sysSlug
 */
export function generateLlmAgent(){
  const now = new Date();
  // 获取时区偏移量（分钟）
  const offsetMinutes = now.getTimezoneOffset();
  // 将当前时间减去偏移量，得到本地时间的ISO字符串
  const localIsoString = new Date(now.getTime() - offsetMinutes * 60000).toISOString();
  // 移除分隔符、时区和毫秒部分
  const timestamp = localIsoString
    .replace(/[-:T.]/g, '')  // 移除分隔符
    .slice(0, 14);          // 截取前14位（YYYYMMDDHHmmss）
  return 'BuildSpeak'+timestamp
}

/**
 * 阻塞
 * @param ms
 * @returns {Promise<unknown>}
 */
export function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

/**
 * 处理get请求中的参数信息
 * 将url中跟随的参数与params中的参数组装成一个完整的对象
 * @param url
 * @param params
 * @returns {{}}
 */
export function tansGetParams(url,params) {
  let result = {}
  if (params) {
    for (const propName of Object.keys(params)) {
      const value = params[propName];
      if (value !== null && value !== "" && typeof (value) !== "undefined") {
        result[propName] = value
      }
    }
  }
  let urlParams = getUrlParams(url);
  if (urlParams) {
    for (const propName of Object.keys(urlParams)) {
      const value = urlParams[propName];
      if (value !== null && value !== "" && typeof (value) !== "undefined") {
        result[propName] = value
      }
    }
  }
  return result
}

/**
 * 提取 URL 中的查询参数，转为对象
 * @param {string} [url=window.location.href] - 可选：要解析的 URL（默认当前页面 URL）
 * @param {Object} [options={}] - 可选配置
 * @param {boolean} [options.parseArray=true] - 是否解析数组参数（如 ?ids=1&ids=2 → {ids: [1,2]}）
 * @param {boolean} [options.parseBoolean=true] - 是否解析布尔值（如 ?isShow=true → {isShow: true}）
 * @returns {Object} 解析后的参数对象
 */
function getUrlParams(url = window.location.href, options = {}) {
  const {
    parseArray = true,
    parseBoolean = true
  } = options;

  const paramsObj = {};
  // 1：先分割 hash（# 后面的部分直接丢弃，不属于查询参数）
  const urlWithoutHash = url.split('#')[0];
  // 提取 ? 后面的查询字符串
  const queryStr = urlWithoutHash.split('?')[1];

  if (!queryStr) return paramsObj; // 无查询参数时返回空对象

  // 分割参数对（过滤空字符串，避免 ?&a=1 这类无效分隔）
  const paramPairs = queryStr.split('&').filter(pair => pair.trim() !== '');

  paramPairs.forEach(pair => {
    // 分割 key 和 value（支持 value 含 = 符号）
    const [key, ...valueParts] = pair.split('=');
    const rawKey = key.trim();
    // 拼接 value（处理 a=b=c 这类场景）
    let rawValue = valueParts.join('=').trim();

    // 过滤空键（如 ?=123 这类无意义参数）
    if (rawKey === '') return;

    // 1. URL 解码（处理中文、特殊字符）
    const decodeKey = decodeURIComponent(rawKey);
    let decodeValue = decodeURIComponent(rawValue);

    // 2. 处理空值（如 ?key= → undefined）
    if (decodeValue === '') {
      decodeValue = undefined;
    } else {
      // 3. 解析布尔值（可选配置）
      if (parseBoolean) {
        if (decodeValue === 'true') decodeValue = true;
        else if (decodeValue === 'false') decodeValue = false;
      }

      // 4. 解析数字（整数/浮点数）
      if (typeof decodeValue === 'string' && /^-?\d+(\.\d+)?$/.test(decodeValue)) {
        decodeValue = Number(decodeValue);
      }
    }

    // 5. 解析数组参数（可选配置）
    if (parseArray && Object.prototype.hasOwnProperty.call(paramsObj, decodeKey)) {
      // 若键已存在，转为数组
      if (!Array.isArray(paramsObj[decodeKey])) {
        paramsObj[decodeKey] = [paramsObj[decodeKey]];
      }
      paramsObj[decodeKey].push(decodeValue);
    } else {
      // 首次出现的键，直接赋值
      paramsObj[decodeKey] = decodeValue;
    }
  });

  return paramsObj;
}
